package com.dxy.df.modules.es;/**
 * Created by cxf_dxy on 2019/10/26.
 */

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @author: XiaoFeng Cui (cuixiaofeng@dxy.cn)
 * @date : 2019/10/26
 * @description:
 */

@Service
public class EsSearchServiceImpl implements IEsSearchService {

    @Autowired
    @Qualifier("articleRepository")
    private ArticleRepository articleRepository;

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    @Override
    public List<ArticleBean> findById(String id) {

        Optional<ArticleBean> articleBean = articleRepository.findById(id);
        if(articleBean.isPresent()){
            return (List<ArticleBean>) articleBean.get();
        }
        return null;
    }

    @Override
    public List<ArticleBean> search(String value) {
        String preTag = "<font color='#dd4b39'>";//google的色值
        String postTag = "</font>";

        MatchPhraseQueryBuilder mpq1 = QueryBuilders
                .matchPhraseQuery("title",value);

        MatchQueryBuilder mpq2= QueryBuilders
                .matchQuery("content",value);


        QueryBuilder qb2 = QueryBuilders.boolQuery()
                .should(mpq1).should(mpq2);
        SearchQuery searchQuery = new NativeSearchQueryBuilder().
                withQuery(qb2)
                .withHighlightFields(new HighlightBuilder.Field("title").preTags(preTag).postTags(postTag),
                        new HighlightBuilder.Field("content").preTags(preTag).postTags(postTag)).build();

        AggregatedPage<ArticleBean> articleBeans = elasticsearchTemplate.queryForPage(searchQuery,ArticleBean.class,new SearchResultMapper() {
            @Override
            public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
                List<ArticleBean> articleBeanList = new ArrayList<>();
                for (SearchHit searchHit : response.getHits()) {
                    if (response.getHits().getHits().length <= 0) {
                        return null;
                    }
                    ArticleBean articleBean = new ArticleBean();
                    //name or memoe
                    HighlightField title = searchHit.getHighlightFields().get("title");
                    if (title != null) {
                        articleBean.setTitle(title.fragments()[0].toString());
                    }
                    HighlightField content = searchHit.getHighlightFields().get("content");
                    if (content != null) {
                        articleBean.setTitle(content.fragments()[0].toString());
                    }else {
                        articleBean.setContent(searchHit.getSourceAsMap().get("content").toString());
                    }
                    articleBean.setId(Integer.valueOf(searchHit.getSourceAsMap().get("id").toString()));
                    articleBeanList.add(articleBean);
                }
                if (articleBeanList.size() > 0) {
                    return new AggregatedPageImpl<>((List<T>) articleBeanList);
                }
                return null;
            }

            public <T> T mapSearchHit(SearchHit var1, Class<T> var2){
                return null;
            }
        });
        return articleBeans.getContent();
    }
}
